package cn.com.yang.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * AIO服务器
 *
 * @Author 杨亿金
 * @Date 2021/11/14 21:13
 * @CopyRight
 * @Version
 */
public class AIOServer {
    private final int port;

    public AIOServer(int port) {
        this.port = port;
        listen();
    }

    private void listen() {
        try {
            //1.创建线程池
            ExecutorService executorService = Executors.newCachedThreadPool();
            //2.创建异步线程组 大小1
            AsynchronousChannelGroup threadGroup = AsynchronousChannelGroup.withCachedThreadPool(executorService, 1);
            //创建异步socket
            final AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open(threadGroup);
            //绑定监听端口
            serverSocketChannel.bind(new InetSocketAddress(port));
            System.out.println("【服务器】已启动，监听端口：" + port);

            serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
                final ByteBuffer buffer = ByteBuffer.allocateDirect(1024);

                @Override
                public void completed(AsynchronousSocketChannel result, Object attachment) {
                    System.out.println("A/O 操作成功，开始获【客户端】取数据...");
                    try {
                        buffer.clear();
                        result.read(buffer).get();
                        buffer.flip();
                        //result.write(buffer);
                        result.write(ByteBuffer.wrap("我收到客户端的消息了!".getBytes()));
                        //result.write(buffer).get();
                        buffer.flip();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    }finally {
                        try {
                            result.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        serverSocketChannel.accept(null,this);
                    }
                    System.out.println("操作完成 获取【客户端】数据结束！");
                }

                @Override
                public void failed(Throwable exc, Object attachment) {
                    System.out.println("I/O 操作失败："+exc);
                }
            });
            try {
                Thread.sleep(Integer.MAX_VALUE);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        int port = 8080;
        new AIOServer(port);
    }
}
